www.gusucode.com > VC++ 自制SQL数据库,含有服务端+客户端-源码程序 > VC++ 自制SQL数据库,含有服务端+客户端-源码程序/code/Server/ServerDoc.cpp
//Download by http://www.NewXing.com // ServerDoc.cpp : implementation file // #include "stdafx.h" #include "miniSQL.h" #include "ServerDoc.h" #include "ServerView.h" #include "ConnectDlg.h" #include "User.h" #include "table.h" #include "SockExec.h" #include "Error.h" #include "AdrDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CMiniSQLApp theApp; ///////////////////////////////////////////////////////////////////////////// // CServerDoc IMPLEMENT_DYNCREATE(CServerDoc, CDocument) CServerDoc::CServerDoc() { m_pSocket = NULL; } BOOL CServerDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; CConnectDlg dlg; if( dlg.DoModal() == IDOK ) { m_pSocket = new CListeningSocket( this ); if( m_pSocket->Create( dlg.m_port + 700, SOCK_STREAM, dlg.m_address ) ) { if( m_pSocket->Listen() ) { Message( "Successful creating ServeR!" ); return TRUE; } } else { if( AfxMessageBox( "创建SOCKET失败,要重试吗?", MB_ICONQUESTION | MB_YESNO ) == IDYES ) return OnNewDocument(); } } ::Message( "Error creating socket or user aborted!\n" ); return FALSE; } CServerDoc::~CServerDoc() { if( m_pSocket ) delete m_pSocket; theApp.m_bConnection = FALSE; } BEGIN_MESSAGE_MAP(CServerDoc, CDocument) //{{AFX_MSG_MAP(CServerDoc) ON_COMMAND(ID_ADDRESS, OnAddress) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CServerDoc diagnostics #ifdef _DEBUG void CServerDoc::AssertValid() const { CDocument::AssertValid(); } void CServerDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CServerDoc serialization void CServerDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ((CEditView*)m_viewList.GetHead())->SerializeRaw(ar); } } ///////////////////////////////////////////////////////////////////////////// // CServerDoc commands BOOL CServerDoc::OnSaveDocument(LPCTSTR lpszPathName) { return CDocument::OnSaveDocument( lpszPathName ); } void CServerDoc::DeleteContents() { delete m_pSocket; m_pSocket = NULL; while( !m_connectionList.IsEmpty() ) { CClientSocket* pSocket = ( CClientSocket* )m_connectionList.RemoveHead(); CMsg msg( SERVER_CLOSE ); msg.m_bClose = TRUE; SendMsg( pSocket, msg ); if( !pSocket->IsAborted() ) { pSocket->ShutDown(); BYTE buffer[ 50 ]; while( pSocket->Receive( buffer, 50 ) > 0 ); delete pSocket; } } CDocument::DeleteContents(); } BOOL CServerDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; return TRUE; } void CServerDoc::ProcessPendingAccept() { CClientSocket* pSocket = new CClientSocket( this ); if( m_pSocket->Accept( *pSocket ) ) { pSocket->Init(); m_connectionList.AddTail( pSocket ); } else delete pSocket; } void CServerDoc::ProcessPendingRead(CClientSocket *pSocket) { do { CMsg* pMsg = ReadMsg( pSocket ); if( pMsg->m_bClose ) { if( pSocket->m_name.GetLength() ) { CString text( pMsg->m_msgList.GetHead() ); CString address, strPort; UINT port; pSocket->GetPeerName( address, port ); strPort.Format( "%d", port ); text += (CString)" (from " + address + ":" + strPort + ") has disconnected from the server."; Message( text ); } CloseSocket( pSocket ); break; } switch( pMsg->m_cmdID ) { case LOGON: { CString name, code; name = pMsg->m_msgList.RemoveHead(); code = pMsg->m_msgList.RemoveHead(); CMsg msg( LOGON ); if( msg.m_nCount = (int)UserLogon( name, code ) ) { pSocket->m_name = name; pSocket->m_type = (DWORD)msg.m_nCount; CString text = name; CString address, strPort; UINT port; pSocket->GetPeerName( address, port ); strPort.Format( "%d", port ); text += (CString)" (from " + address + ":" + strPort + ") has connected to the server."; Message( text ); SendMsg( pSocket, msg ); msg.Init(); msg.m_cmdID = FILEBAR_INIT; PreScanFile( msg ); SendMsg( pSocket, msg ); } else SendMsg( pSocket, msg ); } break; case FILEBAR_EXPAND: { CString tname = pMsg->m_msgList.GetHead(); CMsg msg( FILEBAR_EXPAND ); ScanFile( tname, msg ); SendMsg( pSocket, msg ); } break; case COMMAND: { CSockExec* pExec = new CSockExec( pMsg->m_msgList.GetHead(), pSocket, this ); try { pExec->Exec(); } catch( Error& e ) { CString text( "ERRORS OCCOR, PROCESS ABORTED : \r\n\t" ); text += e.GetErrStr(); Message( text ); CMsg msg( FAILED ); msg.m_nCount = pExec->LineNo() - 1; msg.m_msgList.AddTail( e.GetErrStr() ); CString str; str.Format( "%d", e.m_ErrType ); msg.m_msgList.AddTail( str + "\n" ); SendMsg( pSocket, msg ); delete pExec; } } break; case STEP_COMMAND: { CSockExec* pExec = new CSockExec( pMsg->m_msgList.GetHead(), pSocket, this ); try { pExec->SingleExec(); } catch( Error& e ) { CString text( "ERRORS OCCOR, PROCESS ABORTED : \r\n\t" ); text += e.GetErrStr(); Message( text ); CMsg msg( FAILED ); msg.m_nCount = pExec->LineNo() - 1; msg.m_msgList.AddTail( e.GetErrStr() ); CString str; str.Format( "%d", e.m_ErrType ); msg.m_msgList.AddTail( str ); SendMsg( pSocket, msg ); delete pExec; } } break; default: ; } } while( !pSocket->m_pArchiveIn->IsBufferEmpty() ); } CMsg* CServerDoc::ReadMsg(CClientSocket *pSocket) { static CMsg msg; TRY { pSocket->ReceiveMsg( msg ); } CATCH(CFileException, e) { Message( "Error reading socket!" ); msg.m_bClose = TRUE; pSocket->Abort(); } END_CATCH return &msg; } void CServerDoc::SendMsg(CClientSocket *pSocket, CMsg &msg) { TRY { pSocket->SendMsg( msg ); } CATCH( CFileException, e ) { pSocket->Abort(); Message( "Error sending message!" ); } END_CATCH } void CServerDoc::Message(LPCTSTR lpszMessage) { ( (CServerView*)m_viewList.GetHead() )->Message( lpszMessage ); } void CServerDoc::CloseSocket(CClientSocket *pSocket) { pSocket->Close(); POSITION pos, temp; for( pos = m_connectionList.GetHeadPosition(); pos; ) { temp = pos; CClientSocket* pSock = ( CClientSocket* )m_connectionList.GetNext( pos ); if( pSock == pSocket ) { m_connectionList.RemoveAt( temp ); break; } } delete pSocket; } DWORD CServerDoc::UserLogon(CString& name, CString& code) { if( name == _T("admin") && code == _T("admin") ) return LOG_ADMIN; else if( name == _T("superuser") && code == _T("superuser") ) return LOG_SUPERUSER; else if( name == _T("user") && code == _T("user") ) return LOG_USER; else { CFileStatus status; CString path( theApp.dir ); path += "\\user.dat"; if( CFile::GetStatus( path, status ) ) { CFile File( path, CFile::modeRead ); CArchive ar( &File, CArchive::load ); int length = 0; ar>>length; for( int i = 0; i < length; i++ ) { CUser user; user.Serialize( ar ); if( name == user.m_user && code == user.m_code ) return user.m_type; } return 0; } else { CFile File( path, CFile::modeCreate | CFile::modeWrite ); CArchive ar( &File, CArchive::store ); int length = 0; ar<<length<<'\0'; return 0; } } } void CServerDoc::PreScanFile( CMsg& msg ) { WIN32_FIND_DATA FileData; HANDLE hFind; hFind = ::FindFirstFile( ".\\*.msl", &FileData); if( hFind != INVALID_HANDLE_VALUE ){ CString fname = FileData.cFileName; int len = fname.GetLength(); msg.m_msgList.AddTail( fname.Left( len - 4 ) ); while( ::FindNextFile(hFind, &FileData) ){ fname = FileData.cFileName; len = fname.GetLength(); msg.m_msgList.AddTail( fname.Left( len - 4 ) ); } } } void CServerDoc::ScanFile( CString& tname, CMsg& msg ) { CTable table( (LPCTSTR) tname ); msg.m_nCount = table.attr.attr.num; for( int i = 0; i < table.attr.attr.num; i++ ) { CString str; str = table.attr.attr.attr[i].name; str += ":"; switch( table.attr.attr.attr[i].type.id ) { case _INT: str += "int"; break; case _LONG: str += "long"; break; case _FLOAT: str += "float"; break; case _DATE: str += "date"; break; case _STRING: CString temp; temp.Format( "char[%d]", table.attr.attr.attr[i].type.size - 2 ); str += temp; break; } msg.m_msgList.AddTail( str ); } for( i = 0; i < table.attr.index_num; i++ ) { CString str( _T("index:") ); str += table.attr.index_table[i]; msg.m_msgList.AddTail( str ); } } void CServerDoc::ShowAddress() { CAdrDlg dlg; CString address, strPort; UINT port; m_pSocket->GetSockName( address, port ); strPort.Format( "%d", port ); address += " : " + strPort; dlg.m_address = address; dlg.DoModal(); } void CServerDoc::OnAddress() { ShowAddress(); }